package monitorRepo

import (
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"ruoyi/domain/entity/common"
	"ruoyi/domain/entity/monitor"
	"ruoyi/domain/entity/response"
	"ruoyi/domain/repository"
	"ruoyi/infrastructure/persistence/sysytmRepo"
	"ruoyi/utils"
	"strconv"
	"time"
)

type SysOperationLogRepo struct {
	db *gorm.DB
}

func SysOperationLogRepository(db *gorm.DB) *SysOperationLogRepo {
	return &SysOperationLogRepo{db}
}

var _ repository.SysOperationLogRepository = &SysOperationLogRepo{}

func (o *SysOperationLogRepo) SelectOperationLogList(params common.SearchTableDataParam) common.TableDataInfo {
	var pageNum = params.PageNum
	var pageSize = params.PageSize
	offset := (pageNum - 1) * pageSize

	sysOperLog := params.Other.(monitor.SysOperLog)

	var rows []monitor.SysOperLog

	var beginTime = params.Params.BeginTime
	var endTime = params.Params.EndTime

	var total int64
	var db = o.db.Model(&rows)

	var title = sysOperLog.Title
	if title != "" {
		db.Where("title like concat('%', ?, '%')", title)
	}
	var businessType = sysOperLog.BusinessType
	if businessType != "" {
		db.Where("business_type = ?", businessType)
	}

	/*目前没有用*/
	//var businessTypes = sysOperLog.BusinessTypes
	//if businessTypes != nil || len(businessTypes) > 0 {
	//	//db.Table("users").Where("id in ? ",[]int{1,2,3}).Find(&user)
	//	db.Where("business_type in ?", businessTypes)
	//}

	var status = sysOperLog.Status
	if status != "" {
		db.Where("status = ?", status)
	}

	var oper_name = sysOperLog.OperName
	if oper_name != "" {
		db.Where("oper_name like concat('%', ?, '%')", oper_name)
	}
	var orderByColumn = params.OrderByColumn
	var isAsc = params.IsAsc

	if orderByColumn != "" {
		if "ascending" == isAsc {
			if "operTime" == orderByColumn {
				db.Order("oper_time DESC")
			}
			if "operName" == orderByColumn {
				db.Order("oper_name DESC")
			}
		}
		if "descending" == isAsc {
			if "operTime" == orderByColumn {
				db.Order("oper_time ASC")
			}
			if "operName" == orderByColumn {
				db.Order("oper_name ASC")
			}
		}
	}

	if beginTime != "" {
		//Loc, _ := time.LoadLocation("Asia/Shanghai")
		//startTime1, _ := time.ParseInLocation(constants.DateFormat, beginTime, Loc)
		//endTime = endTime + " 23:59:59"
		//endTime1, _ := time.ParseInLocation(constants.DateFormat, endTime, Loc)
		startTime1, endTime1 := utils.GetBeginAndEndTime(beginTime, endTime)
		//db.Where("oper_time >= ? and oper_time <= ?", startTime1, endTime1)
		db.Where("oper_time >= ?", startTime1)
		db.Where("oper_time <= ?", endTime1)
	}

	db.Order("oper_id desc")
	if err := db.Table(sysOperLog.TableName()).Count(&total).Error; err != nil {
		return common.Fail()
	}
	if err := db.Limit(pageSize).Offset(offset).Find(&rows).Error; err != nil {
		return common.Fail()
	}

	if rows == nil {
		return common.Fail()
	} else {
		return common.Success(rows, total)
	}
}

func (o *SysOperationLogRepo) DeleteOperationLog(operIds []int) response.Response {
	if err := o.db.Where("oper_id in (?)", operIds).Delete(&monitor.SysOperLog{}).Error; err != nil {
		return response.ReturnFailMsg(err.Error())
	}
	return response.ReturnSuccess("操作成功")
}

func (o *SysOperationLogRepo) ClearOperationLog() response.Response {
	if err := o.db.Exec("truncate table sys_oper_log").Error; err != nil {
		return response.ReturnFailMsg(err.Error())
	}
	return response.ReturnSuccess("操作成功")
}

func (o *SysOperationLogRepo) OperationLogAdd(context *gin.Context, param monitor.SysOperLog) response.Response {
	userId, _ := context.Get("userId")
	sysUser := sysytmRepo.SysUserRepository(o.db).FindUserById(userId)
	dept := sysytmRepo.SysDeptRepository(o.db).GetDeptInfo(strconv.Itoa(sysUser.DeptId))
	ip := utils.GetRemoteClientIp(context.Request)

	param.RequestMethod = context.Request.Method
	param.OperName = sysUser.UserName
	param.DeptName = dept.DeptName
	param.OperUrl = context.Request.URL.Path
	param.OperIp = ip
	param.OperTime = time.Now()
	param.OperLocation = "" + utils.GetRealAddressByIP(ip)
	if err := o.db.Model(&monitor.SysOperLog{}).Create(&param).Error; err != nil {
		return response.ReturnFailMsg(err.Error())
	}
	return response.ReturnSuccess("操作成功")
}
